package cn.smbms.service.impl;

import java.sql.Connection;
import java.util.List;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.smbms.dao.UserMapper;
import cn.smbms.pojo.User;
import cn.smbms.service.UserService;
@Service("userService")
// Map userCache = new HashMap();
@CacheConfig(cacheNames="userCache")
public class UserServiceImpl implements UserService {
	@Autowired
	private UserMapper userMapper;
	
	// service 存在意义：1、事务；2、缓存
	
	@Override
	//@CachePut(key="#user.id")
	@CacheEvict(key="#user.id")
	public int updateUser(User user) {
		//
		return userMapper.modify(user);
	}

	@Override
	// userCache.remove(id)
	@CacheEvict(key="#id")
	public int delUser(Integer id) {
		//
		return userMapper.deleteUserById(id);
	}

	@Override
	// userCache.put(id, 方法的返回值)
	@Cacheable(key="#id")
	public User getUser(Integer id) {
		//
		return userMapper.getUserById(id);
	}

	@Override
	public List<User> getUserLists(User user) {
		//
		return userMapper.getUserLists(user);
	}
	
	@Override
	public User getUser(String userCode) {
		//
		return userMapper.getUser(userCode);
	}
	
	@Override
	public int count() {
		return userMapper.count();
	}

	@Override
	public List<User> getUserList() {
		return userMapper.getUserList();
	}
	
	@Override
	public int add(User user) {
		return userMapper.add(user);
	}
	
	/////////////// 事务处理  ///////////////
	@Autowired
	private DataSource dataSource;

	//1、数据库连接由IOC容器管理，例如使用 JdbcTemplate 等封装
	@Transactional
	public int del(User user) throws Exception {
		//涉及事务的传播
		//1、默认REQUIRED：如果当前没有事务，就新建一个事务 
		//如果已经存在一个事务中，加入到这个事务中。
		//2、REQUIRES_NEW：不管有没有，都创建一个。日志接口。
		
		//3、NESTED：如果当前存在事务，则在嵌套事务内执行。
		//如果当前没有事务，就新建一个事务，则执行与REQUIRED类似的操作。
		this.modify(user);
		Connection conn = null;
		try {
		conn = dataSource.getConnection();
		conn.setAutoCommit(false);//手动提交
		//
		conn.commit();
		} catch(Exception e) {
			conn.rollback();
		} finally {
			conn.close();
		}
		return 0;
	}
	
	@Autowired
	private JdbcTemplate jdbcTemplate; //模板方法，策略模式
	
	public int delete(User user) throws Exception {
		String sql = "delete";
		try{
			jdbcTemplate.execute(sql);
			return 1;
		}catch(Exception e){
			return 0;
		}
	}
	//2、默认只处理 RuntimeException 异常，例如 NullPointException 等
	/**
	 * service 存在的意义
	 * 1、一个服务接口同时调用多个 dao 接口，生成订单的服务接口（订单表、购物车、库存表、用户表）
	 * 2、不仅调用多个接口，更重要的是保持数据库中表数据的一致性（事务）
	 * @throws Exception 
	 */
	@Override
	@Transactional(rollbackFor=Exception.class)
	public int modify(User user) throws Exception {
		//订单表、库存表，调用省略
		//调用用户表
		int i = userMapper.modify(user);
		//最终购物车表
		if(i == 1) {//spring事务控制默认只识别运行时异常
			//throw new RuntimeException("清空购物车出错");
			throw new Exception("清空购物车出错");
		}
		return i;
	}


}
